#!/usr/bin/python
import os
import sys
import MySQLdb
import string
import time
import cloud
import pp
import db
import remoteExeCommand
import testVmIsAlive

def isDigtal(Num):
    nums = string.digits
    myNum = str(Num)
    if type(myNum) is not str:
        return False
    else:
        for temp in myNum:
            if temp not in nums:
                return False
        return True

#def expectandshow(child, expect):
#	index=child.expect(expect)
#	#print child.before,child.after,
#	return index
#
#def checkAllVM(ip,password):
#	cmd="ssh " + ip	
#   	scp_child=pexpect.spawn(cmd)
#   	index=expectandshow(scp_child, \
#                 ['Are you sure you want to continue connecting', \
#                 "password:",pexpect.TIMEOUT, pexpect.EOF])
#	if index == 0:
#		scp_child.sendline('yes')
#		index1=expectandshow(scp_child, ["password:",pexpect.TIMEOUT, pexpect.EOF])
#		if index1 == 0:
#			scp_child.sendcontrol('c')
#			expectandshow(scp_child, [pexpect.EOF])
#		else:
#			expectandshow(scp_child, [pexpect.EOF])
#		return 0
#	elif index == 1:
#		scp_child.sendcontrol('c')
#		expectandshow(scp_child, [pexpect.EOF])
#		return 0
#	else: 
#		return 1
#
#
#def set_no_pwd(ip,username,password,ssh_port):
#    client = paramiko.SSHClient()
#    client.load_system_host_keys()
#    client.connect((ip), username=(username), password=(password), port=(ssh_port))
#    sftpclient = client.open_sftp()
#    sftpclient.put("/root/.ssh/id_rsa.pub","/root/.ssh/id_rsa.pub",callback=None)
#    sftpclient.close()
#    #client.close()
#
#    cmd = "cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys; chmod 600 /root/.ssh/authorized_keys"
#    #client=paramiko.SSHClient()
#    #client.load_system_host_keys()
#    #client.connect((ip), username=(username), password=(password), port=(ssh_port))
#    stdin,stdout,stderr = client.exec_command(cmd)
#    print stdout.read()
#    client.close()
#
## Set Mpi Environment ##

def set_etc_host( host_address, username, all_host_list):
    #cmd = "ssh "+username+"@" + host_address + " \"echo \'127.0.0.1       localhost.localdomain localhost\' > /etc/hosts;"
    cmd = "\"echo \'127.0.0.1       localhost.localdomain localhost\' > /etc/hosts;"
    for aip in all_host_list:
        cmd += "echo \'"+aip+" "+aip+"\' >> /etc/hosts;"
    cmd += "/bin/hostname "+host_address +";"
    cmd += " echo '' > /etc/hosts.equiv;"

    for ip1 in all_host_list:
        cmd += "echo \'" +ip1 + "\' >> /etc/hosts.equiv;"
    cmd += "echo '' > /root/.rhosts;"
    for ip2 in all_host_list:
        cmd += "echo \'" +ip2 + "\' >> /root/.rhosts;"
    HOSTNAME=host_address
    NETWORKING="yes"
    NETWORKING_IPV6="no"
    cmd += " echo \'" + "NETWORKING="+NETWORKING+"\' > /etc/sysconfig/network;" \
        + "echo \'NETWORKING_IPV6=" + NETWORKING_IPV6 + "\' >> /etc/sysconfig/network ;" \
        + "echo \'HOSTNAME=" + HOSTNAME + "\' >> /etc/sysconfig/network;\" "
    flag,result = remoteExeCommand.sshCmd(host_address,username,cmd)
    return not flag

def set_salve_nfs_rsh(Salve_IP,Master_IP,username):
    #cmd = "ssh "+username+"@" + Salve_IP + " \"sed -i \'7d\' /etc/fstab;" + \
    cmd = "\"sed -i \'7d\' /etc/fstab;" + \
          "echo \'"+ Master_IP+":/home /home nfs defaults 0 0\' >> /etc/fstab ;" + \
         "/sbin/chkconfig netfs on;" + \
                "mount /home;" + \
                "/sbin/chkconfig rsh on;" + \
                "/etc/init.d/xinetd start;\""
    #out = os.popen(cmd)
    #print out.read()
    flag,result = remoteExeCommand.sshCmd(Salve_IP,username,cmd)
    return not flag

def set_master_rsh(Master_IP,username):
    #cmd ="ssh "+username+"@" + Master_IP + " \"/sbin/chkconfig rsh on;" + \
    cmd = "\"/sbin/chkconfig rsh on;" + \
         "/etc/init.d/xinetd start;\""
    #out = os.popen(cmd)
    #print out.read()    
    
    flag,result = remoteExeCommand.sshCmd(Master_IP,username,cmd)
    return not flag

def set_master_nfs(Master_IP,username):
    #cmd = "ssh "+username+"@" + Master_IP + " \"/sbin/chkconfig nfs on;" + \
    cmd = "\"/sbin/chkconfig nfs on;" + \
                "/sbin/chkconfig nfslock on;" + \
        	"/etc/init.d/nfslock start;" + \
        	"/etc/init.d/nfs start;\""
    #out = os.popen(cmd)
    #print out.read()
    flag,result = remoteExeCommand.sshCmd(Master_IP,username,cmd)
    return not flag

def set_mpd_port(Master_IP, total_ip, username, all_host_list):
    #cmd = "ssh "+username+"@" + Master_IP + " \""
    cmd = "\""
    cmd += "echo '' > /root/mpd.hosts;"
    for ip in all_host_list:
        cmd += "echo "+ip+" >> /root/mpd.hosts;"
    cmd += "echo '' > /home/cgcl/all_vm_ip_list;"
    for ip in all_host_list:
        cmd += "echo "+ip+" >> /home/cgcl/all_vm_ip_list;"
    cmd += "mpdallexit; mpdboot --rsh=rsh -n "+str(total_ip)+" --file=/root/mpd.hosts; \""
    flag,result = remoteExeCommand.sshCmd(Master_IP,username,cmd)
    return not flag
    #out = os.popen(cmd)
    #print out.read()

def get_ip_list(job_id,conn):
    all_host_list=[]
    total_ip = 0
    cnt,rows = db.exeFetchCommand(conn,"select vm_ip from env_resource, vm_info where env_id="+str(job_id)+" and env_resource.vm_id=vm_info.vm_id and vm_info.vm_type='master'")
    all_host_list.append(rows[0][0])
    total_ip += 1
    
    cnt,rows = db.exeFetchCommand(conn,"select vm_ip from env_resource, vm_info where env_id="+str(job_id)+" and env_resource.vm_id=vm_info.vm_id and vm_info.vm_type='salve'")
    for temp in rows:
        all_host_list.append(temp[0])
        total_ip += 1
    return all_host_list,total_ip

def set_mpi_env(all_host_list,total_ip):
    try:  
        #print all_host_list
        username="root"
        Master_IP=all_host_list[0]
        ppservers = ()
        job_server = pp.Server(total_ip, ppservers=ppservers)
        jobs = []
        index = 0
        while index < total_ip:
            host_address=all_host_list[index]
            jobs.append(job_server.submit(set_etc_host, (host_address,username,all_host_list,), (),("remoteExeCommand",)))
            index += 1
        for job in jobs:
            flag = job()
            if not flag:
                return -6

        ppservers = ()
        job_server = pp.Server(2, ppservers=ppservers)
        jobs4 = []
        jobs4.append(job_server.submit(set_master_nfs, (Master_IP,username,), (), ("remoteExeCommand",)))
        jobs4.append(job_server.submit(set_master_rsh, (Master_IP,username,), (), ("remoteExeCommand",)))
        for job in jobs4:
            flag = job()
            if not flag:
                return -6
        ppservers = ()
        job_server = pp.Server(total_ip-1, ppservers=ppservers)
        jobs1 = []
        index = 1
        while index < total_ip:
            host_address=all_host_list[index]
            jobs1.append(job_server.submit(set_salve_nfs_rsh, (host_address,Master_IP,username,), (), ("remoteExeCommand",)))
            index += 1
        for job in jobs1:
            flag = job()
            if not flag:
                return -6
        flag = set_mpd_port(Master_IP,total_ip,username,all_host_list)
        if not flag:
            return -6
        return 1
    except:
        #exception
        return -5

def checkSetMpiEnvPara( conn,job_id ):
    try:  
        if not conn:
            #print "Can not connect to database, Fail!"
            return -1
        if not isDigtal(job_id):
            return -2
        cnt,rows = db.exeFetchCommand(conn,"select env_id from mpi_env where status='running' and env_id="+str(job_id))  
        if cnt != 1:
            #print "Not job ",job_id
            return -2
        #print job_id
        return 1
    except:
        #exception
        return -5

def setMpiEnv(env_id):
    try:  
        flag = testVmIsAlive.checkVmIsAlive(env_id)
        if flag < 0:
            return flag
        
        connect=db.connectDB()
        conn=db.cursorDB(connect)
        flag = checkSetMpiEnvPara(conn,env_id)
        # flag = -1: database connection fail.
        # flag = -2: Parameter error.
        # flag = -5: exception
        if flag < 0:
    	    db.closeCursor(conn)
            db.closeConnect(connect)
            return flag
        all_host_list,total_ip = get_ip_list(env_id,conn)
        # Set fail.
        flag = set_mpi_env(all_host_list,total_ip)
        #flag = -5: exception.
        #flag = -6: set fail.
        if flag < 0:
            return flag
        db.closeCursor(conn)
        db.closeConnect(connect)
    
        # test mpi environment
        #flag = testmpi(env_id)
        # flag = 1: successful.
        return flag

    except:
        #exception
        return -5


